package datamodels

import (
	"micro-oauth/utils"
	"strconv"
	"time"
)

type TokenType string
type GrantType string

const (
	Bearer TokenType = "Bearer"
	JWT    TokenType = "JWT"
)

const (
	AuthorizationCode GrantType = "authorization_code"
	Implicit          GrantType = "implicit"
	ClientCredential  GrantType = "client_credential"
)

// Alter SQL:
// alter table oauth_token alter column token_type type varchar(20) using token_type::varchar(20);
//
// alter table oauth_token alter column scope_code type varchar(20) using scope_code::varchar(20);
//
//alter table oauth_token alter column request_state type varchar(20) using request_state::varchar(20);
//
//create index tb_oauth_user_partner_id_index on oauth_user (partner_id);
//create index tb_oauth_user_role_relation_user_id_index on oauth_user_role_relation (user_id);
//create index tb_oauth_user_role_relation_role_id_index on oauth_user_role_relation (role_id);
//create index tb_oauth_role_partner_id_index on oauth_role (partner_id);
//create index tb_oauth_role_permission_relation_role_id_index on oauth_role_permission_relation (role_id);
//create index tb_oauth_role_permission_relation_permission_id_index on oauth_role_permission_relation (permission_id);
//create index tb_oauth_permission_partner_id_index on oauth_role (partner_id);
//create index tb_oauth_permission_api_relation_permission_id_index on oauth_permission_api_relation (permission_id);
//create index tb_oauth_permission_api_relation_api_id_index on oauth_permission_api_relation (api_id);
//create index tb_oauth_api_partner_id_index on oauth_role (partner_id);

type Token struct {
	MyGormModel
	AccessToken      string    `gorm:"size:255;unique_index"`
	RefreshToken     string    `gorm:"size:255;unique_index"`
	RefreshExpiresIn time.Time `gorm:"type:timestamptz"`
	ExpiresIn        time.Time `gorm:"type:timestamptz"`

	GrantType    GrantType `gorm:"size:20"`
	TokenType    TokenType `gorm:"size:20"`
	ScopeCode    string    `grom:"size:20"` // 这个scope是oauth2中的scope概念
	RequestState string    `gorm:"size:20"`

	UserId    uint64 `json:"user_id,string" gorm:"index"`
	ClientId  uint64 `json:"client_id,string"`
	PartnerId uint64 `json:"partner_id,string" gorm:"index"`

	ScopeId    uint64 `json:"scope_id,string" gorm:"default:0;index"` // 这个scope是下的partner下的细分
	TerminalId uint64 `json:"terminal_id,string" gorm:"default:0"`
	DeviceUUID string `json:"device_uuid" gorm:"column:device_uuid;index;size:100"`
	User       *User
	Client     *Client
}

func (t *Token) ToQueryString() string {
	switch t.GrantType {
	case AuthorizationCode:
		data := map[string]string{
			"access_token":  t.AccessToken,
			"token_type":    string(t.TokenType),
			"expires_in":    strconv.FormatInt(t.ExpiresIn.Unix(), 10),
			"refresh_token": strconv.FormatInt(t.RefreshExpiresIn.Unix(), 10),
			"scope":         t.ScopeCode,
		}
		return utils.MapToQueryString(data)
	case Implicit:
		data := map[string]string{
			"access_token":  t.AccessToken,
			"refresh_token": t.RefreshToken,
			"token_type":    string(t.TokenType),
			"expires_in":    strconv.FormatInt(t.ExpiresIn.Unix(), 10),
			"state":         strconv.FormatInt(t.RefreshExpiresIn.Unix(), 10),
			"scope":         t.ScopeCode,
		}
		return utils.MapToQueryString(data)
	default:
		return ""
	}
}
